#pragma once
#include <iostream>
#include <string>
#include <functional>
#include<memory>
#include<sys/wait.h>
#include "Socket.hpp"


namespace TcpServerModule
{
    using namespace LogModule;
    using namespace SocketModule;
    using tcphandler_t = std::function<bool(SockPtr, InetAddr)>;
    class TcpServer
    {
    public:
        TcpServer(int port):_port(port),
        _isrunning(false),
        _listensockptr(std::make_unique<TcpSocket>())
        {}
        void InitServer(tcphandler_t task)
        {
            _task=task;
            _listensockptr->BuildTcpSockeMethod(_port);
        }
        void Loop()
        {
            _isrunning = true;
            while(_isrunning)
            {
                InetAddr client;
                auto sockfd=_listensockptr->Accepter(&client);
                if(sockfd==nullptr)
                {
                    continue;
                }
                LOG(LogLevel::INFO)<<"accept a client from "<<client.Addr();

                //子进程处理
                pid_t pid=fork();
                if(pid==0)
                {
                    //子进程处理
                    _listensockptr->close();
                    if(fork()==0) exit(0);
                    _task(sockfd,client);
                    exit(0);
                }
                
                sockfd->close();
                ::waitpid(pid,nullptr,0);

            }
            _isrunning=false;
        }
        ~TcpServer()
        {
            _listensockptr->close();
        }

    private:
        std::unique_ptr<TcpSocket> _listensockptr;
        int _port;
        bool _isrunning;
        tcphandler_t _task;
    };
}